/*=========================================================================

Program:   Virtual Surgery
Language:  C++
Date:      2009-9-1
Version:   0.1
Mail:		   nelfylee@gmail.com

Copyright (c) 2009 Nelfy Lee. All rights reserved.

=========================================================================*/
#ifndef _LOAD_SERIES_DICOM_THREAD_H_
#define _LOAD_SERIES_DICOM_THREAD_H_

#include "LoadDataThreadBase.h"
#include "VolumeSource.h"
#include "PipelineModel.h"

#include "itkGDCMImageIO.h"
#include "itkGDCMSeriesFileNames.h"
#include "itkImageSeriesReader.h"
#include "itkCastImageFilter.h"
#include "itkImageFileWriter.h"
#include "itkShrinkImageFilter.h"

template<class TImageType>
class LoadDicomSeriesThread : public LoadDataThread<TImageType>
{
public:
	LoadDicomSeriesThread(const QString &dir, PipelineModel *pipeline) : LoadDataThread<TImageType>(dir, pipeline) {}

protected:
	void run()
	{
		typedef itk::ImageSeriesReader<TImageType>	ReaderType;
		typedef itk::GDCMImageIO                    ImageIOType;
		typedef itk::GDCMSeriesFileNames            NamesGeneratorType;

		ImageIOType::Pointer gdcmIO = ImageIOType::New();
		NamesGeneratorType::Pointer namesGenerator = NamesGeneratorType::New();

		namesGenerator->SetInputDirectory( (const char*)LoadDataThread<TImageType>::filename.toLatin1());

        typename ReaderType::FileNamesContainer filenames = namesGenerator->GetInputFileNames();

		unsigned int numberOfFilenames =  filenames.size();
		std::cout << "Loaded :" << numberOfFilenames << " files." << std::endl; 

		typename LoadDataThreadBase::ProgressCommandType::Pointer progressCmd = LoadDataThreadBase::ProgressCommandType::New();
		progressCmd->SetCallbackFunction( this, &LoadDicomSeriesThread::ProcessEvent );

		typename ReaderType::Pointer reader = ReaderType::New();

		emit LoadDataThread<TImageType>::emitProgressStart(QString("Loading dicom images..."));

		reader->SetImageIO( gdcmIO );
		reader->SetFileNames( filenames );
		reader->AddObserver( itk::ProgressEvent(), progressCmd.GetPointer());
		reader->Update();

		LoadDataThread<TImageType>::m_image = reader->GetOutput();

		// these things should be done in factory

// 		VolumeSource<TImageType> *source = new VolumeSource<TImageType>(QString("BASE#%1").arg(m_pipeline->getFreeSubID()));
// 		source->setVolume(reader->GetOutput());
// 		source->setFileName(filename);
// 
// 		m_pipeline->addSource(source);

		emit LoadDataThread<TImageType>::emitProgressDone();
	}

};


template<class TImageType>
class LoadVtkFileThread : public LoadDataThread<TImageType>
{
    typedef itk::ImageFileReader<TImageType> ImageFileReaderType;
    
public:
	LoadVtkFileThread(const QString &filename, PipelineModel *pipeline) : LoadDataThread<TImageType>(filename, pipeline) 
    {
        m_filename = filename;
    }

protected:
	void run()
	{
		typename LoadDataThreadBase::ProgressCommandType::Pointer progressCmd = LoadDataThreadBase::ProgressCommandType::New();
		progressCmd->SetCallbackFunction( this, &LoadVtkFileThread::ProcessEvent );

		typename ImageFileReaderType::Pointer reader = ImageFileReaderType::New();

		emit LoadDataThread<TImageType>::emitProgressStart(QString("Loading dicom image..."));

		reader->SetFileName(m_filename.toLatin1().data());
		reader->AddObserver(itk::ProgressEvent(), progressCmd.GetPointer());
		reader->Update();

		LoadDataThread<TImageType>::m_image = reader->GetOutput();

		emit LoadDataThread<TImageType>::emitProgressDone();
	}

    QString m_filename;
};





#endif


